package com.duowan.cms.common.repository;

import java.util.Date;
import java.util.List;

import org.apache.ibatis.builder.xml.dynamic.ForEachSqlNode;
import org.apache.ibatis.mapping.BoundSql;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.mapping.ParameterMapping;
import org.apache.ibatis.mapping.ParameterMode;
import org.apache.ibatis.reflection.MetaObject;
import org.apache.ibatis.reflection.property.PropertyTokenizer;
import org.apache.ibatis.session.Configuration;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.type.TypeHandlerRegistry;

import com.duowan.cms.common.util.DateUtil;

public class MyBatisSQLHelper {

    public static String getSql(SqlSession session, String methodName, Object parameterObject) {
        Configuration config = session.getConfiguration();
        MappedStatement ms = config.getMappedStatement(methodName);
        BoundSql boundSql = ms.getBoundSql(parameterObject);
        String sql = boundSql.getSql();
        List<ParameterMapping> parameterMappings = boundSql.getParameterMappings();
        
        TypeHandlerRegistry typeHandlerRegistry = ms.getConfiguration().getTypeHandlerRegistry();
        
        if (parameterMappings != null) {
            MetaObject metaObject = parameterObject == null ? null : session.getConfiguration().newMetaObject(parameterObject);
            for (int i = 0; i < parameterMappings.size(); i++) {
              ParameterMapping parameterMapping = parameterMappings.get(i);
              if (parameterMapping.getMode() != ParameterMode.OUT) {
                Object value;
                String propertyName = parameterMapping.getProperty();
                PropertyTokenizer prop = new PropertyTokenizer(propertyName);
                if (parameterObject == null) {
                  value = null;
                } else if (typeHandlerRegistry.hasTypeHandler(parameterObject.getClass())) {
                  value = parameterObject;
                } else if (boundSql.hasAdditionalParameter(propertyName)) {
                  value = boundSql.getAdditionalParameter(propertyName);
                } else if (propertyName.startsWith(ForEachSqlNode.ITEM_PREFIX)
                    && boundSql.hasAdditionalParameter(prop.getName())) {
                  value = boundSql.getAdditionalParameter(prop.getName());
                  if (value != null) {
                    value = config.newMetaObject(value).getValue(propertyName.substring(prop.getName().length()));
                  }
                } else {
                  value = metaObject == null ? null : metaObject.getValue(propertyName);
                }
                if(null != sql && sql.indexOf("?") != -1 && value != null){
                    if(value instanceof Date){
                        sql = sql.replaceFirst("\\?", "'" + DateUtil.convertDate2Str((Date)value) + "'");
                    }else if(value instanceof Boolean || value instanceof Integer || value instanceof Long){
                        sql = sql.replaceFirst("\\?", value.toString());
                    }else{
                        sql = sql.replaceFirst("\\?", "'" + value.toString() + "'");
                    }
                }
              }
            }
          }
        
        return sql;
    }
    
    public static void main(String[] args) {
        String sql = "select * from t_test where userid = ?";
        sql = sql.replaceFirst("\\?", "yzq");
        System.out.println(sql);
    }
}
